Amazon ECS が利用するコンテナイメージのスケジューリングロジックが変更されました

Amazon ECS が利用するコンテナイメージのスケジューリングロジックが変更されました

Amazon ECS が利用するコンテナイメージのスケジューリングロジックが変更されました。イメージダイジェストをコントロールプレーンに保管することによりサービス内のコンテナの一貫性を保つ仕様になりました。
Clock Icon2024.09.22

こんにちは!AWS 事業本部コンサルティング部のたかくに(@takakuni_)です。

かなり前なのですが Amazon ECS が利用するコンテナイメージのスケジューリングロジックが変更されました。

https://aws.amazon.com/about-aws/whats-new/2024/07/amazon-ecs-software-version-consistency-containerized-applications/

AWS Blog も公開されていますね。

https://aws.amazon.com/jp/blogs/containers/announcing-software-version-consistency-for-amazon-ecs-services/

今まで

今までをおさらいします。 Amazon ECS で latest タグを使ってコンテナをデプロイしているとします。

Untitled(89).png

ECR へ同じ latest タグを付与して、新しいイメージをプッシュした場合、次のようにタグの置き代わりが発生します。

Untitled(89) (1).png

タグの起き代わりが発生したのちに、タスクのスケーリング(Desired Count の変更)が起きた場合、 ECS サービスは latest タグが付与されている、イメージダイジェスト b のコンテナイメージを利用してスケジューリングを行う仕様でした。

Untitled(89) (2).png

この仕様の場合、サービス内で latest タグを見ているけれども、イメージダイジェスト(コンテナイメージの中身)が異なるコンテナが混在するようなことが懸念されてきました。

Untitled(89) (3).png

これから

今回のアップデートで、スケーリング(Desired Count の変更)が行われても、古いイメージダイジェストでスケジューリングを行うようになりました。

ECS へのデプロイ時にコントロールプレーン側に、利用したイメージダイジェストを保管し、スケーリング時はコントロールプレーンに保管されたイメージダイジェストを利用する仕様になりました。

Desired Count が 3 だと仮定した場合、次の挙動になります。

  1. デプロイメント発生時に Desired Count の数(今回だと 3)にかかわらず、 1 つのタスク起動を試みる
  2. 起動したタスクのイメージタグに対応するイメージダイジェストを解決する
  3. 解決されたイメージダイジェストをコントロールプレーンに保管する
  4. コントロールプレーンに保管されたイメージダイジェストを利用して他のタスクを起動する

Untitled(90).png

注意点

いくつか注意点がありますので記載します。

  1. 挙動 1 の 「Desired Count の数にかかわらず」は Desired Count が 0 のサービスには発生しない
    1. Desired Count が 1 以上のデプロイメントにおいてイメージダイジェストの解決が発生する
    2. Desired Count が 0 のデプロイメントの場合は、Desired Count が 1 以上になった時点でイメージダイジェストの名前解決を試みる
  2. イメージダイジェストの解決が 3 回以上失敗すると、イメージダイジェストを解決せずにデプロイメントが続行される(タグベースのデプロイが行われる)
    1. デプロイメントサーキットブレーカーが有効になっている場合は、デプロイメントが失敗しロールバックされる
  3. イメージダイジェストの解決は以下のプラットフォームバージョン以上である必要がある
    1. Fargate Linux 1.4.0, Fargate Windows 1.0.0
    2. Amazon ECS Agent 1.31.0 以上
      1. Amazon ECS Agent 1.31.0 から 1.69.0 までは ECR にプッシュされたイメージの解決までを対応
  4. GuardDuty セキュリティエージェントや Service Connect プロキシなど、Amazon ECS が管理するサイドカーコンテナのダイジェストはキャプチャしない
  5. ECS へ新しいデプロイメントを作成することでイメージダイジェストの解決が再度実行される

https://docs.aws.amazon.com/AmazonECS/latest/developerguide/deployment-type-ecs.html#deployment-container-image-stability

やってみる

百聞は一見にしかずということで、やってみます。

ECR には latest タグで Nginx のコンテナイメージをプッシュしている状態です。

2024-09-21 at 16.45.11-Elastic Container Registry - Images.png

まずはタスク定義を作成します。 latest タグを参照するよう、コンテナイメージの指定しました。リビジョンは 2 になっていますが、タイポを書き換えただけなので、気にしないでください。

2024-09-21 at 16.41.04-Task definition containers  Elastic Container Service  ap-northeast-1.png

ECS サービスの作成

それでは、 ECS サービスの作成します。

注意書きの、 Desired Count 0 のデプロイメントの挙動を確認したいため、 0 の状態でサービス(デプロイメント)を作成します。

2024-09-21 at 16.47.05-Create service  Elastic Container Service  ap-northeast-1.png

挙動の通り、 Desired Count が 0 の場合は、 ECS タスクが起動しませんでした。(まあ、そうですよね。)

2024-09-21 at 16.49.14-Service deployments  Elastic Container Service  ap-northeast-1.png

ECS サービスのタスク数を変えてみます。今回は 0 から 3 に変えてみようと思います。

2024-09-21 at 16.51.00-Update service  Elastic Container Service  ap-northeast-1.png

Started At 列を見ると挙動の通り、初めに 1 つのタスクが起動し、遅れて残りのタスクが起動する挙動に見えますね。

2024-09-21 at 16.53.44-Service tasks  Elastic Container Service  ap-northeast-1.png

ECS のイベント欄からも確認できました。タスク ID 3e939b8dc1094a21b6fe91a97a89b5fc が初めに起動し、残りの10f66aeb5ea1421387fd1cae32055b82, c93c097fc6e548e283d3042ed4c1163f が起動していますね。

2024-09-21 at 16.54.46-Service deployments  Elastic Container Service  ap-northeast-1.png

latest タグの更新

latest タグの更新します。更新により旧イメージ sha256:993e から始まるイメージダイジェストのタグが外れていますね。

2024-09-21 at 17.06.35-Elastic Container Registry - Images.png

Desired Count の値を 3 から 5 に変更してみます。(アップデート前は latest タグを見る挙動でした。)

2024-09-21 at 17.09.07-Update service  Elastic Container Service  ap-northeast-1.png

latest タグがついていた sha256:993e で始まるイメージダイジェストで起動していますね。

2024-09-21 at 17.12.15-Service tasks  Elastic Container Service  ap-northeast-1.png

イベント欄をみると、初回デプロイメントのようなイメージダイジェストの解決が行われることなく、タスクが起動していることがわかります。

2024-09-21 at 17.13.43-Service deployments  Elastic Container Service  ap-northeast-1.png

新しいデプロイの強制

Force new deployment オプションを利用して v2 へ更新してみます。タスクの起動数はそのままにしておきます。

2024-09-21 at 17.15.39-Update service  Elastic Container Service  ap-northeast-1.png

デプロイメントが始まりました。 新しいデプロイのため、代表で 1 つのコンテナが起動していますね。

2024-09-21 at 17.17.13-Service tasks  Elastic Container Service  ap-northeast-1.png

イベント欄からも同様の挙動が確認できます。

2024-09-22 at 06.52.07-Service events  Elastic Container Service  ap-northeast-1.png

タスク定義のリビジョンを更新してみる

新しいデプロイによって、イメージの解決が行われるということは、 サービスで利用しているタスク定義のリビジョン更新も該当します。(いわゆるいつものデプロイのことです)

タスク定義のリビジョンを更新したデプロイを行ってみます。

2024-09-22 at 07.20.44-Update service  Elastic Container Service  ap-northeast-1@2x.png

同様の挙動が確認できますね。

2024-09-22 at 07.41.34-Service deployments  Elastic Container Service  ap-northeast-1@2x

以前のように同じタイミングでデプロイしたい

各デプロイメントにおいて、1 タスクが代表で起動し、イメージダイジェストの解決、解決したイメージダイジェストをもとに、残りのタスクを起動するような挙動になったため、今までよりデプロイに時間がかかるようになりました。

以前のように、タスクをなるべく同じタイミングでデプロイするには、イメージダイジェストを指定するような方法が言及されています。

To reduce potential latency associated with container image resolution in services with multiple tasks, run Amazon ECS agent version 1.83.0 or higher on EC2 container instances. To avoid potential latency altogether, specify container image digests in your task definition.

https://docs.aws.amazon.com/AmazonECS/latest/developerguide/deployment-type-ecs.html#deployment-container-image-stability

個人的に他に思いつくもので言えば、毛色は異なりますが Feature Flags(App Config)を使ったデプロイとロールアウトの分離なども考えられます。(回避したい目的がロールアウトであればですが。)

参考

https://kaminashi-developer.hatenablog.jp/entry/2023/07/31/122831

https://logmi.jp/tech/articles/329504

まとめ

以上、「Amazon ECS が利用するコンテナイメージのスケジューリングロジックが変更されました」でした。

イメージダイジェストが保管されたことで、一貫したコンテナのスケジューリングは可能になりましたが、latest タグを使っていい理由にはなりません。本番相当での latest タグの利用は変わらず非推奨ですのでご注意ください。

コンテナイメージはコンテナレジストリに保存されます。レジストリ内の各イメージはタグによって識別されます。latest というタグがあります。このタグは、git リポジトリの HEAD と同様に、アプリケーションコンテナイメージの最新バージョンに対するポインターとして機能します。latest タグはテストのみに使用することが推奨されます。ベストプラクティスとして、ビルドごとにコンテナイメージに一意のタグを付けます。イメージの構築に使用された git コミットの git SHA を使用してイメージにタグ付けすることをお勧めします。
コミットごとにコンテナイメージを構築する必要はありません。ただし、特定のコードコミットを本番環境にリリースするたびに、新しいコンテナイメージを構築することをお勧めします。また、イメージに対して、イメージ内のコードの git commit に対応するタグを付けることをお勧めします。イメージに git commit のタグを付けた場合、イメージが実行しているコードのバージョンをより迅速に見つけることができます。

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/container-considerations.html

以上、AWS 事業本部コンサルティング部のたかくに(@takakuni_)でした!

この記事をシェアする

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.